package web.util;

import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.MimeTypeUtils;
import org.springframework.util.StreamUtils;
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.Locale;

import static java.nio.charset.StandardCharsets.UTF_8;
import static org.springframework.http.ContentDisposition.attachment;
import static org.springframework.http.MediaTypeFactory.getMediaType;

public abstract class ResponseUtil {
	/**
	 * @param filename 带后缀
	 * @see MimeTypeUtils
	 */
	public static ResponseEntity<StreamingResponseBody> download(String filename, byte[] bytes) {
		return ResponseEntity.status(HttpStatus.CREATED)
				.contentType(getMediaType(filename).orElse(MediaType.APPLICATION_OCTET_STREAM))
				.headers(h -> h.setContentDisposition(attachment().filename(filename, UTF_8).build()))
				// .header(CONTENT_DISPOSITION, attachment().filename(fullFilename, UTF_8).build().toString())
				.body(body -> StreamUtils.copy(bytes, body));
	}

	/**
	 * @param filename 带后缀
	 * @see MimeTypeUtils
	 */
	public static void download(HttpServletResponse response, String filename, byte[] bytes) {
		response.setLocale(Locale.CHINA);
		// https://blog.csdn.net/u012881904/article/details/104590720
		MediaType mediaType = getMediaType(filename).orElse(MediaType.APPLICATION_OCTET_STREAM);
		response.setContentType(mediaType.toString());
		response.setCharacterEncoding(UTF_8.name());

		try (ServletOutputStream outputStream = response.getOutputStream()) {
			response.setHeader(HttpHeaders.CONTENT_DISPOSITION, downloadNameEncode(filename));
			StreamUtils.copy(bytes, outputStream);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static String downloadNameEncode(String fileName) {
		// HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
		// String header = request.getHeader(HttpHeaders.USER_AGENT).toUpperCase();

		try { // RFC 6266 https://www.cnblogs.com/zhengxl5566/p/13492602.html
			// 对真实文件名进行百分号编码
			String percentEncodedFileName = URLEncoder.encode(fileName, UTF_8.name()).replaceAll("\\+", "%20");
			// 组装 contentDisposition 的值
			StringBuilder contentDispositionValue = new StringBuilder();
			contentDispositionValue.append("attachment; filename=")
					.append(percentEncodedFileName)
					.append(";")
					.append("filename*=")
					.append("utf-8''")
					.append(percentEncodedFileName);
			return contentDispositionValue.toString();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return "attachment; filename=" + fileName + ";target=_blank";
	}
}